iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 15
0
自我挑戰組

Ruby and Rails 的二三事系列 第 15

Ruby and Rails 的二三事 - Day15 Model 之間的關聯

  • 分享至 

  • xImage
  •  

在Rails中,Model之間的關聯(Associations),最容易被誤解的就是:
在每個資料表做一些什麼設定,就可以讓這幾個資料表彼此產生連結。

其實在Rails中的關聯指的是:在 Model 層級的關係上,透過 Model 所提供的一些方法(如: has_one、has_many 或 belongs_to)搭配 Rails 的資料表慣例設定主鍵(Primary Key)及外部鍵(Foreign Key),讓這些資料表串在一起。並產生一些方便實用的語法讓我們可以操作資料庫。

比較常見的資料表關聯大致有以下三種:

  • 一對一
  • 一對多
  • 多對多

一對一

如下圖,我們有兩個 Model: Owner 和 Store,
每個 Owner 都有一間 Store每間 Store 都屬於一個Owner 的ER圖,我們會畫成像下面這樣:

https://ithelp.ithome.com.tw/upload/images/20190928/20116733BoliUhV5P6.png

首先用指令建立出model

rails g model Owner name age:integer
rails g model Store title address phone owner:references

在建立Model後對owner.rb 和 store.rb兩個檔案進行關聯設定:

  • has_one: (每個 Owner 都有一間 Store)
 # app/models/owner.rb
  class Owner < ApplicationRecord
    has_one :store
  end

Owner 會因此得到一些新的方法:

  • store : 找出屬於 Owner 的 Store

  • store= : 將 Store 指派給 Owner

  • build_store : 由 Owner 的角度來建立 Store 資料,需搭配 save 才能將資料寫入資料庫。

  • create_store : 由 Owner 的角度來建立 Store 資料並直接寫入資料庫。

  • belongs_to: (每間 Store 都屬於一個Owner)

 # app/models/store.rb
  class Store < ApplicationRecord
    belongs_to :owner
  end

Store 也會得到一些新的方法:

  • owner : 找出屬於 Store 的 Owner
  • owner= : 將 Owner 指派給 Store

一對多

接下來讓我們加入新的Model Product
每間 Store 都有很多 Product每個 Product 都屬於一個 Store 的ER圖,我們會畫成像下面這樣:
https://ithelp.ithome.com.tw/upload/images/20190928/20116733OLbUcrgb9g.png

一樣,先用指令建立出model:

rails g model Product name price:decimal description:text store:references
  • has_many: (**每個 Store 都有很多 Product **)
 # app/models/store.rb
  class Store < ApplicationRecord
    belongs_to :owner
    has_many :products
  end

Store 會因此得到一些新的方法:

  • products : 找出屬於 Store 的 Product

  • products= : 將 Product 指派給 Store,這時候要用陣列的方式來寫入資料喔!

  • build_store : 由 Store 的角度來建立 Product 資料,需搭配 save 才能將資料寫入資料庫。

  • create_store : 由 Store 的角度來建立 Product 資料並直接寫入資料庫。

  • belongs_to: (每間 Product 都屬於一個 Store)

 # app/models/product.rb
  class Product < ApplicationRecord
    belongs_to :store
  end

這個部分和上面雷同,請請讀者自己嘗試看看吧!


多對多

等等,每間 Store 都有很多 Product每個 Product 都屬於一個 Store,有點不太對吧?
是的,的確不太正確應該是每間 Store 都有很多 Product每個 Product 可以屬於多間 Store,才對。

通常在建立多對多關聯時,我們會建立一個第三方的 Model來儲存雙方的資訊:
https://ithelp.ithome.com.tw/upload/images/20190928/20116733qN4opYIrbj.png

已經很習慣了吧,先用指令建立出model:

rails g model WareHouse store:references product:references
  • 每個 Warehouse 都屬於一個 Store
  • 每個 Warehouse 都屬於一個 Product
 # app/models/ware_house.rb
  class WareHouse < ApplicationRecord
    belongs_to :store
    belongs_to :product
  end

這時候設定要分長兩個部分:
首先是:

  • has_many :每間 Store 都有很多 Warehouse
    但其實我們在意的是,每間 Store 有多少 Product
  • has_many(table_name, {through: :table_name })
# app/models/store.rb
  class Store < ApplicationRecord
    belongs_to :user

    has_many :ware_houses
    has_many :products, through: :ware_houses
  end

這邊和上面一樣,也是要設定兩個部分:

  • has_many :每個 Product 都有很多 Warehouse
  • has_many(table_name, {through: :table_name })
# app/models/product.rb
  class Product < ApplicationRecord
    has_many :ware_houses
    has_many :stores, through: :ware_houses
  end

大概是這樣,其他更進一步的使用方式,有機會再說吧!
鐵人賽,我們明天見!!

參考資料:

RailsGuides
為你自己學Ruby on Rails


上一篇
Ruby and Rails 的二三事 - Day14 Active Record?可以說中文嗎?
下一篇
Ruby and Rails 的二三事 - Day16 && / and /| |/ or
系列文
Ruby and Rails 的二三事19
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言